import React from 'react'

import { Router, useNavigate, } from '../react-router'
export * from '../react-router' // 将 react-router 中的所有内容都暴露出去

import { createHashHistory, createBrowserHistory } from '../history'


export function HashRouter({ children }) {
  let historyRef = React.useRef(null) // 用于存储历史对象的引用
  if (historyRef.current === null) {
    historyRef.current = createHashHistory() // 创建并保存一个 hash 历史对象
  }
  let history = historyRef.current // 获取历史对象
  const [state, setState] = React.useState({
    // history.push 调用后为 PUSH 
    action: history.action, // 最近一次导航的动作 
    location: history.location, // 当前地址的完整描述对象 
  })
  React.useEffect(() => {
    // 浏览器地址变化时会自动执行 listen 方法中的回调函数
    // 回调函数接收2个参数 location 和 action
    // history.listen 方法返回一个取消监听的 unlisten 方法 调用后不会监听浏览器地址变化
    return history.listen(setState)
  }, [history])
  return <Router
    children={children} // 透传子组件
    location={state.location} // 地址对象
    navigationType={state.action} // 导航动作
    navigator={history} // 历史对象
  ></Router>
}

export function BrowserRouter({ children }) {
  // 组件重新渲染不会修改 React.useRef 中保存的值
  let historyRef = React.useRef(null) // 用于存储历史对象的引用
  if (historyRef.current === null) {
    historyRef.current = createBrowserHistory() // 创建并保存一个 browser 历史对象
  }
  let history = historyRef.current // 获取历史对象
  const [state, setState] = React.useState({
    // history.push 调用后为 PUSH 
    action: history.action, // 最近一次导航的动作 
    location: history.location, // 当前地址的完整描述对象 
  })
  React.useEffect(() => {
    // 浏览器地址变化时会自动执行 listen 方法中的回调函数
    // 回调函数接收2个参数 location 和 action
    // history.listen 方法返回一个取消监听的 unlisten 方法 调用后不会监听浏览器地址变化
    return history.listen(setState)
  }, [history])
  return <Router
    children={children} // 透传子组件
    location={state.location} // 浏览器地址的完整描述对象
    navigationType={state.action} // 导航动作
    navigator={history} // 历史对象
  ></Router>
}


/**
 * 跳转路径
 */
export function Link({ to, children }) {
  const navigate = useNavigate()
  return <a href={to} onClick={event => {
    event.preventDefault() // 阻止默认事件
    navigate(to)
  }}>{children}</a>
}
